<!DOCTYPE html>
<html>
<title>Netty Port Mapping</title>
<meta charset="UTF-8"/>
<meta name="author" content="lihuai.chen@163.com"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="js/alertify.css">
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/alertify.js"></script>
<body>
<nav class="navbar navbar-dark fixed-top bg-dark">
    <div class="navbar-brand"><img src="favicon.ico" height="30px"/> <span class="d-none d-md-inline-block">Netty Port Mapping</span>
    </div>
    <div class="d-none d-md-block">
        <div class="form-inline">
            <div class="input-group">
                <input class="form-control" type="search" id="keyword" placeholder="Search"/>
                <div class="input-group-append">
                    <button class="btn btn-outline-success" type="button" id="search">Search</button>
                </div>
            </div>
        </div>
    </div>
    <button class="btn btn-outline-danger ml-5 afterLogin" id="logout">Logout</button>
</nav>
<div class="container-fluid" style="margin-top: 80px">
    <div class="row beforeLogin">
        <div class="col-lg-4 offset-lg-4">
            <div class="form-group">
                <label for="email">Email address</label>
                <input type="email" class="form-control" id="email">
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" id="password">
            </div>
            <button type="button" class="btn btn-primary" id="login">Login</button>
        </div>
    </div>
    <div class="table-responsive afterLogin">
        <table class="table table-bordered table-hover">
            <thead>
            <tr class="bg-light">
                <th>Name</th>
                <th>Local Port</th>
                <th>Remote Host</th>
                <th>Remote Port</th>
                <th>Action <a data-toggle="modal" href="#"
                              class="bg-success rounded small text-white px-1 float-right"
                              data-target="#createModal"> + Add new </a></th>
            </tr>
            </thead>
            <tbody id="dataList">
            </tbody>
        </table>
    </div>
</div>
<div class="fixed-bottom text-center">CopyRight@2021 <a href="https://gitee.com/leefine">leefine.com</a></div>
<div class="modal fade" id="createModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">New Socket Proxy</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="form-group">
                        <label for="name" class="col-form-label text-success">Name</label>
                        <input class="form-control" id="name" type="text" maxlength="50" required></input>
                    </div>
                    <div class="form-group">
                        <label for="localPort" class="col-form-label text-success">Local Port</label>
                        <input class="form-control" id="localPort" type="number" max="99999" required></input>
                    </div>
                    <div class="form-group">
                        <label for="remoteHost" class="col-form-label text-success">Remote Host</label>
                        <input class="form-control" id="remoteHost" type="text" maxlength="30" required></input>
                    </div>
                    <div class="form-group">
                        <label for="remotePort" class="col-form-label text-success">Remote Port</label>
                        <input class="form-control" id="remotePort" type="number" max="99999" required></input>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" id="create">Create</button>
            </div>
        </div>
    </div>
</div>
<script>
    var token = sessionStorage.getItem("token");

    $(function () {
        var checkIP = function (ip) {
            if (ip == 'localhost') return true;
            var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
            if (re.test(ip)) {
                if (RegExp.$1 < 256 && RegExp.$2 < 256 && RegExp.$3 < 256 && RegExp.$4 < 256)
                    return true;
            }
            return false;
        };

        var stateRealtime = function () {
            $('[data-name]').each(function () {
                var name = $(this).attr('data-name');
                $.ajax({
                    url: 'config/state',
                    data: {token: token, name: name},
                    type: 'POST',
                    dataType: 'JSON',
                    success: function (data) {
                        if (data.code == 0) {
                            $('[data-name="' + name + '"]').removeClass();
                            if (data.data == 'Stoped') {
                                $('[data-name="' + name + '"]').attr('data-state', '0');
                                $('[data-control="' + name + '"]').text('Open');
                                $('[data-name="' + name + '"]').addClass('spinner-grow spinner-grow-sm text-danger');
                            } else {
                                $('[data-name="' + name + '"]').attr('data-state', '1');
                                $('[data-control="' + name + '"]').text('Close');
                                $('[data-name="' + name + '"]').addClass('spinner-grow spinner-grow-sm text-success');
                            }
                        }
                    }
                });
            });
            setTimeout(stateRealtime, 10000);
        };

        var loadList = function () {
            $.ajax({
                url: 'config/list',
                data: {token: token, keyword: $('#keyword').val()},
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    if (data.code == 0) {
                        var hmtl = '';
                        $.each(data.data, function (index, item) {
                            hmtl += '<tr><td>' + item.name + ' <span data-name="' + item.name + '"></span></td><td>' + item.localPort + '</td><td>' + item.remoteHost + '</td><td>' + item.remotePort + '</td><td><a class="btn btn-sm btn-danger" data-delete="' + item.name + '" href="#">Delete</a><a class="btn btn-sm btn-info" data-control="' + item.name + '" href="#"></a></td></tr>'
                        });
                        $('#dataList').html(hmtl);

                        stateRealtime();
                    } else {
                        alertify.error(data.data);
                    }
                }
            });
        };

        var checkLogin = function () {
            if (token == null) {
                $('.beforeLogin').show();
                $('.afterLogin').hide();
            } else {
                $('.beforeLogin').hide();
                $('.afterLogin').show();
                loadList();
            }
        };

        checkLogin();

        $('#login').click(function () {
            $.ajax({
                url: 'config/login',
                data: {password: $('#password').val(), email: $('#email').val()},
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    if (data.code == 0) {
                        sessionStorage.setItem("token", token = data.data);
                        checkLogin();
                    } else {
                        alertify.error(data.data);
                    }
                }
            });
        });

        $('#logout').click(function () {
            sessionStorage.removeItem("token");
            window.location.reload();
        });


        $('#search').click(function () {
            loadList();
            //$('#keyword').val('');
        });

        $('#create').click(function () {
            if (!checkIP($('#remoteHost').val())) {
                alertify.error("Remote Host is wrong format!");
                return;
            }
            if ($('#name').val() == null || $('#name').val() == '') {
                alertify.error("Name can not be empty!");
                return;
            }
            if ($('#localPort').val() == null || $('#localPort').val() == '') {
                alertify.error("Local Port can not be empty!");
                return;
            }
            if ($('#remotePort').val() == null || $('#remotePort').val() == '') {
                alertify.error("Remote Port can not be empty!");
                return;
            }

            $.ajax({
                url: 'config/save',
                data: {
                    token: token,
                    name: $('#name').val(),
                    localPort: $('#localPort').val(),
                    remoteHost: $('#remoteHost').val(),
                    remotePort: $('#remotePort').val()
                },
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    if (data.code == 0) {
                        alertify.error(data.data);
                        $('#createModal').modal('hide');
                        loadList();
                    } else {
                        alertify.error(data.data);
                    }
                }
            });
        });

        $(document).on('click', '[data-delete]', function () {
            var name = $(this).attr('data-delete');
            $.ajax({
                url: 'config/delete',
                data: {token: token, name: name},
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    if (data.code == 0) {
                        alertify.error(data.data);
                        loadList();
                    } else {
                        alertify.error(data.data);
                    }
                }
            });
        });

        $(document).on('click', '[data-control]', function () {
            var name = $(this).attr('data-control'),
                openClose = $('[data-name="' + name + '"]').attr('data-state');

            openClose = Math.abs(parseInt(openClose) - 1);

            $.ajax({
                url: 'config/control',
                data: {token: token, name: name, openClose: openClose},
                type: 'POST',
                dataType: 'JSON',
                success: function (data) {
                    if (data.code == 0) {
                        alertify.error(data.data);
                        loadList();
                    } else {
                        alertify.error(data.data);
                    }
                }
            });
        });
    });
</script>
</body>
</html>